package com.example.person.service.impl;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.support.ExcelTypeEnum;
import com.alibaba.excel.write.metadata.style.WriteCellStyle;
import com.alibaba.excel.write.metadata.style.WriteFont;
import com.alibaba.excel.write.style.HorizontalCellStyleStrategy;
import com.alibaba.excel.write.style.column.SimpleColumnWidthStyleStrategy;
import com.example.person.common.JsonPage;
import com.example.person.common.ServiceCode;
import com.example.person.common.ServiceException;
import com.example.person.entity.Person;
import com.example.person.entity.PersonDTO;
import com.example.person.entity.PersonExcelVO;
import com.example.person.entity.PersonVO;
import com.example.person.lister.PersonReadLister;
import com.example.person.mapper.PersonMapper;
import com.example.person.service.IPersonService;
import com.example.person.utils.IdUtils;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.BorderStyle;
import org.apache.poi.ss.usermodel.FillPatternType;
import org.apache.poi.ss.usermodel.HorizontalAlignment;
import org.apache.poi.ss.usermodel.IndexedColors;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLEncoder;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

/**
 * @author sytsnb@gmail.com
 * @date 2023 2023/3/10 16:37
 */
@Slf4j
@Service
public class PersonServiceImpl implements IPersonService {

    @Autowired
    private PersonMapper personMapper;

    @Override
    public void addNew(PersonDTO personDTO) {
        List<PersonVO> list = personMapper.listByPerson(Person.builder()
                .mobilePhone(personDTO.getMobilePhone())
                .build());

        if (list.size() > 0) {
            throw new ServiceException(ServiceCode.ERR_CONFLICT, "该手机号码已注册");
        }

        Person person = new Person();
        BeanUtils.copyProperties(personDTO, person);
        String uuid = IdUtils.getId();
        person.setId(uuid);
        person.setCreateTime(LocalDateTime.now());
        person.setUpdateTime(LocalDateTime.now());
        int rows = personMapper.insert(person);
        if (rows != 1) {
            throw new ServiceException(ServiceCode.ERR_INSERT, "Error inserting");
        }
    }

    @Override
    public void deleteById(String id) {
        PersonVO personVO = personMapper.getById(id);
        if (personVO == null) {
            throw new ServiceException(ServiceCode.ERR_NOT_FOUND, "删除人员信息失败，尝试访问的数据不存在！");
        }
        int i = personMapper.deleteById(id);
        System.out.println("deleteById = " + i);
        if (i != 1) {
            throw new ServiceException(ServiceCode.ERR_DELETE, "删除失败,服务器繁忙!!");
        }
    }

    @Override
    public void deleteByIds(String[] ids) {
        List<PersonVO> list = personMapper.getByIds(ids);
        if (list.size() == 0) {
            throw new ServiceException(ServiceCode.ERR_NOT_FOUND, "删除人员信息失败，尝试访问的数据不存在！");
        }
        int i = personMapper.deleteByIds(ids);
        System.out.println("deleteByIds = " + i);
        if (i < 1) {
            throw new ServiceException(ServiceCode.ERR_DELETE, "删除失败,服务器繁忙!!");
        }
    }

    @Override
    public void updateById(String id, PersonDTO personDTO) {
        PersonVO personVO = personMapper.getById(id);
        if (personVO == null) {
            throw new ServiceException(ServiceCode.ERR_NOT_FOUND, "更新人员信息失败，尝试访问的数据不存在！");
        }
        Person person = new Person();
        BeanUtils.copyProperties(personDTO, person);
        person.setId(id);
        person.setUpdateTime(LocalDateTime.now());
        int i = personMapper.update(person);
        if (i != 1) {
            throw new ServiceException(ServiceCode.ERR_NOT_ALLOWED, "更新失败,服务器繁忙!!");
        }
    }

    @Override
    public PersonVO getById(String id) {
        return null;
    }

    @Override
    public List<PersonVO> getByIds(String[] ids) {
        return personMapper.getByIds(ids);
    }

    @Override
    public List<PersonVO> selectList() {
        return personMapper.list();
    }

    @Override
    public List<PersonVO> selectList(PersonDTO personDTO) {
        Person person = new Person();
        if (personDTO != null) {
            BeanUtils.copyProperties(personDTO, person);
        }
        List<PersonVO> list = personMapper.listByPerson(person);
        return list;
    }

    /**
     * 后端列表分页 未使用
     *
     * @param page
     * @param pageSize
     * @return
     */
    @Override
    public JsonPage<PersonVO> list(Integer page, Integer pageSize) {
        log.debug("查询列表，页码={}，每页记录数={}", page, pageSize);
        PageHelper.startPage(page, pageSize);
        List<PersonVO> personVOList = personMapper.list();
        log.debug("查询分页列表：page={}，size={}", page, pageSize);
        System.out.println("personVOList = " + personVOList.size());
        return JsonPage.restPage(new PageInfo<>(personVOList));
    }

    /**
     * 下载excel模板
     *
     * @param response
     * @throws IOException
     */
    @Override
    public void downloadExcelTemplate(HttpServletResponse response) throws IOException {
        List<PersonExcelVO> list = new ArrayList<>();

        PersonExcelVO personExcelVO = new PersonExcelVO();
        personExcelVO.setName("姓名");
        personExcelVO.setFullNameSpelling("姓名全拼");
        personExcelVO.setGender("性别");
        personExcelVO.setIdCardType("身份证类型");
        personExcelVO.setIdNo("身份证号");
        personExcelVO.setBirthDate("出生日期");
        personExcelVO.setMobilePhone("手机号");
        personExcelVO.setEmail("电子邮箱");

        list.add(personExcelVO);

        // 头的策略
        WriteCellStyle headWriteCellStyle = new WriteCellStyle();
        // 背景设置为白色
        headWriteCellStyle.setFillForegroundColor(IndexedColors.WHITE.getIndex());
        //居中
        headWriteCellStyle.setHorizontalAlignment(HorizontalAlignment.CENTER);

        //字体
        WriteFont headWriteFont = new WriteFont();
        headWriteFont.setFontHeightInPoints((short) 18);
        headWriteCellStyle.setWriteFont(headWriteFont);

        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetem.sheet;charset=utf-8");
        response.setCharacterEncoding("utf-8");

        //要导出的文件名
        String fileName = URLEncoder.encode("人员信息数据模板", "UTF-8").replaceAll("\\+", "%20");
        response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx");
        EasyExcel.write(response.getOutputStream())
                .head(Object.class)
                .excelType(ExcelTypeEnum.XLSX)
                //表中左下角的名字
                .sheet("人员信息表模板")
                .registerWriteHandler(new SimpleColumnWidthStyleStrategy(20))
                .doWrite(list);
    }

    @Override
    public void exportExcel(HttpServletResponse response, String[] ids) throws IOException {
        List<PersonVO> list = new ArrayList<PersonVO>();
        if (ids.length > 0) {
            list = personMapper.getByIds(ids);
        } else {
            list = personMapper.list();
        }
        // 头的策略
        WriteCellStyle headWriteCellStyle = new WriteCellStyle();
        // 背景设置为白色
        headWriteCellStyle.setFillForegroundColor(IndexedColors.WHITE.getIndex());
        WriteFont headWriteFont = new WriteFont();
        headWriteFont.setFontHeightInPoints((short) 13);
        headWriteCellStyle.setWriteFont(headWriteFont);
        // 内容的策略
        WriteCellStyle contentWriteCellStyle = new WriteCellStyle();
        // 这里需要指定 FillPatternType 为FillPatternType.SOLID_FOREGROUND 不然无法显示背景颜色.头默认了 FillPatternType所以可以不指定
        contentWriteCellStyle.setFillPatternType(FillPatternType.SOLID_FOREGROUND);

        //设置边框
        contentWriteCellStyle.setBorderLeft(BorderStyle.THIN);
        contentWriteCellStyle.setBorderTop(BorderStyle.THIN);
        contentWriteCellStyle.setBorderRight(BorderStyle.THIN);
        contentWriteCellStyle.setBorderBottom(BorderStyle.THIN);

        // 背景白色
        contentWriteCellStyle.setFillForegroundColor(IndexedColors.WHITE.getIndex());
        WriteFont contentWriteFont = new WriteFont();
        // 字体大小
        contentWriteFont.setFontHeightInPoints((short) 13);
        contentWriteCellStyle.setWriteFont(contentWriteFont);
        // 这个策略是 头是头的样式 内容是内容的样式 其他的策略可以自己实现
        HorizontalCellStyleStrategy horizontalCellStyleStrategy =
                new HorizontalCellStyleStrategy(headWriteCellStyle, contentWriteCellStyle);

        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetem.sheet;charset=utf-8");
        response.setCharacterEncoding("utf-8");

        //要导出的文件名
        String fileName = URLEncoder.encode("人员信息", "UTF-8").replaceAll("\\+", "%20");
        response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx");

        EasyExcel.write(response.getOutputStream())
                .head(PersonVO.class)
                .excelType(ExcelTypeEnum.XLSX)
                //表中左下角的名字
                .sheet("人员信息表")
                .registerWriteHandler(horizontalCellStyleStrategy)
                .doWrite(list);
    }

    @Override
    public void uploadExcel(MultipartFile file) throws IOException {
        EasyExcel.read(
                file.getInputStream(),
                PersonVO.class,
                new PersonReadLister(personMapper))
                .sheet(0)
                .headRowNumber(1)
                .doRead();
    }
}
